package com.lagou.handler;

import com.lagou.pojo.RpcRequest;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component
public class UserServerHandler  extends SimpleChannelInboundHandler<RpcRequest> implements ApplicationContextAware {

    //获取ApplicationContext对象
    private static ApplicationContext applicationContext;

    /**
     * 提供外部正确可调用方法
     */
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        this.channelRead0(ctx, (RpcRequest) msg);
    }

    /**
     * 实际执行方法
     * @param ctx
     * @param request
     * @throws Exception
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcRequest request) throws Exception {
        //获取类名
        String className = request.getClassName();
        //以下两种途径都能正常执行得出结果

        //通过applicationContext获取service实现类
        Object serviceBean = applicationContext.getBean(className);
        //获取入参，并通过class.getMethod方法找到需要实际执行的方法
        Method method = serviceBean.getClass().getMethod(request.getMethodName(), request.getParameterTypes());
        //进行执行，写入返回结果
        ctx.writeAndFlush(method.invoke(serviceBean, request.getParameters()));
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        if(this.applicationContext == null) {
            this.applicationContext = applicationContext;
        }
    }
}
